package com.ruoyi.common.utils.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.event.ProgressListener;
import com.aliyun.oss.model.*;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhengxiang
 * @data 2021/6/16 16:24
 */
public class OSSUtils {

    private static String endpoint = "http://oss-cn-wuhan-lr.aliyuncs.com";
    private static String accessKeyId = "LTAI4Fhbx9idKsMYvJZ73voq";
    private static String accessKeySecret = "WpIlz8sF4Suf0cRTfyeoSjAivCCOmC";
    private static String buketName = "abzy-video";

    /**
     * 普通上传视频带进度条
     *
     * @param bucketName
     * @param objectName
     */
    public static void uploadVideoProgressBar(String filePath, String bucketName, String objectName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 上传文件的同时指定了进度条参数。
            ossClient.putObject(new PutObjectRequest(bucketName, objectName, new File(filePath)).
                    <PutObjectRequest>withProgressListener(new PutObjectProgressListener()));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
    }

    /**
     * 断点续传,带进度条  上传视频
     *
     * @param bucketName     存储空间
     * @param fileName       上传后的文件名（路径+文件名）
     * @param localFilePath  待上传的视频路径
     * @param checkpointFile 记录分片下载进度路径
     */
    public static void breakpointContinuingly(String bucketName, String fileName, String localFilePath, String checkpointFile, String fileType) throws Throwable {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        ObjectMetadata meta = new ObjectMetadata();
        // 指定上传的内容类型。
        meta.setContentType(fileType);
        // 文件上传时设置访问权限ACL。
        // meta.setObjectAcl(CannedAccessControlList.Private);
        // 通过UploadFileRequest设置多个参数。
        // 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
        UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, fileName);
        // 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        uploadFileRequest.setUploadFile(localFilePath);
        // 指定上传并发线程数，默认值为1。
        uploadFileRequest.setTaskNum(5);
        // 指定上传的分片大小。
        uploadFileRequest.setPartSize(1 * 1024 * 1024);
        // 开启断点续传，默认关闭。
        uploadFileRequest.setEnableCheckpoint(true);
        // 记录本地分片上传结果的文件。上传过程中的进度信息会保存在该文件中。
        uploadFileRequest.setCheckpointFile(checkpointFile);
        // 文件的元数据。
        uploadFileRequest.setObjectMetadata(meta);
        //进度条
        uploadFileRequest.setProgressListener(new PutObjectProgressListener());
        // 断点续传上传。
        ossClient.uploadFile(uploadFileRequest);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 普通下载文件 带进度条
     *
     * @param bucketName
     * @param fileName
     * @param localPath
     */
    public static void downloadFile(String bucketName, String fileName, String localPath) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 下载Object到本地文件，并保存到指定的本地路径中。如果指定的本地文件存在会覆盖，不存在则新建。
        // 如果未指定本地路径，则下载后的文件默认保存到示例程序所属项目对应本地路径中。
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fileName);
        getObjectRequest.setProgressListener(new GetObjectProgressListener());
        ossClient.getObject(getObjectRequest, new File(localPath));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 断点续传下载视频
     *
     * @param bucketName     存储空间
     * @param fileName       上传后的文件名（路径+文件名）
     * @param localFilePath  待上传的视频路径
     * @param checkpointFile 记录分片下载进度路径
     * @throws Throwable
     */
    public static void breakpointDownload(String bucketName, String fileName, String localFilePath, String checkpointFile) throws Throwable {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 下载请求，10个任务并发下载，启动断点续传。
        DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, fileName);
        downloadFileRequest.setDownloadFile(localFilePath);
        downloadFileRequest.setPartSize(1 * 1024 * 1024);
        downloadFileRequest.setTaskNum(10);
        downloadFileRequest.setEnableCheckpoint(true);
        downloadFileRequest.setCheckpointFile(checkpointFile);
        downloadFileRequest.setProgressListener(new GetObjectProgressListener());
        // 下载文件。
        DownloadFileResult downloadRes = ossClient.downloadFile(downloadFileRequest);
        // 下载成功时，会返回文件元信息。
        downloadRes.getObjectMetadata();
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 获取所有视频列表
     *
     * @param bucketName 存储空间
     * @param KeyPrefix  文件前缀
     */
    public static List<String> getVideoList(String bucketName, String KeyPrefix, String companyOnlyNumber) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 列举文件。如果不设置KeyPrefix，则列举存储空间下的所有文件。如果设置KeyPrefix，则列举包含指定前缀的文件。
        ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request();
        listObjectsV2Request.setMaxKeys(1000);
        listObjectsV2Request.setBucketName(bucketName);
        listObjectsV2Request.setPrefix(companyOnlyNumber + KeyPrefix);
        ListObjectsV2Result listObjectsV2Result = ossClient.listObjectsV2(listObjectsV2Request);
        // 列举文件。
        List<OSSObjectSummary> objectSummaries = listObjectsV2Result.getObjectSummaries();
        List<String> cloudCourseUrl = new ArrayList<>();
        for (OSSObjectSummary s : objectSummaries) {
            String[] split = s.getKey().split(companyOnlyNumber + "/");
            cloudCourseUrl.add(split[1]);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return cloudCourseUrl;
    }

    /**
     * 分页获取文件列表
     *
     * @param bucketName
     * @param KeyPrefix
     * @param companyOnlyNumber
     * @return
     */
    public static List<String> getVideoListByPage(String bucketName, String KeyPrefix, String companyOnlyNumber, int pageSize, String pageNumber) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ObjectListing objectListing;
        List<String> cloudCourseUrl = new ArrayList<>();
        do {
            objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).
                    withPrefix(companyOnlyNumber + KeyPrefix).withMarker(pageNumber).withMaxKeys(pageSize));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            for (OSSObjectSummary s : sums) {
                String[] split = s.getKey().split(companyOnlyNumber + "/");
                cloudCourseUrl.add(split[1]);
            }
            //下一个文件
            pageNumber = objectListing.getNextMarker();
        } while (objectListing.isTruncated());
        // 关闭OSSClient。
        ossClient.shutdown();
        return cloudCourseUrl;
    }

    /**
     * 获取文件在线访问地址
     * @param buketName
     * @param objectName
     * @return
     */
    public static String getObjectUrl(String buketName,String objectName) {
        return "https://"+buketName+".oss-cn-wuhan-lr.aliyuncs.com/"+objectName;
    }
    /**
     * 上传文件
     * @param inputStream  文件流
     * @param fileName 文件名 例如exampledir/exampleobject.txt
     * @param buketName
     */
    public static void putObject(InputStream inputStream, String fileName, String buketName){
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件流。
        ossClient.putObject(buketName, fileName, inputStream);
        // 关闭OSSClient。
        ossClient.shutdown();
    }
    /**
     * 删除文件
     */
    public static void delFile( String fileName, String objectName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.deleteObject(objectName,fileName);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 普通上传带进度条
     *
     * @param bucketName
     * @param objectName
     */
    public static void uploadFileProgressBar(String filePath, String bucketName, String objectName, ProgressListener progressListener) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 上传文件的同时指定了进度条参数。
            if(progressListener != null){
                ossClient.putObject(new PutObjectRequest(bucketName, objectName, new File(filePath)).
                        <PutObjectRequest>withProgressListener(progressListener));
            }else{
                ossClient.putObject(new PutObjectRequest(bucketName, objectName, new File(filePath)));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
    }

    public static void main(String[] args) throws Throwable {
//                OSSUtils.uploadVideo("C:\\Users\\Administrator\\Desktop\\work\\video\\course\\1\\3f3fae3f93994407a6d09ba197368976.mp4","abkj-test");
//        OSSUtils.uploadVideoProgressBar("C:\\video\\course/1/20899203.mp4", buketName, "a82898608dee482181a8a973359ae1c0/course/1/10101000.mp4");
        //        OSSUtils.downloadFile("abkj-test","course/1/10101000.mp4","C:\\Users\\Administrator\\Desktop\\work\\video\\course\\1\\10101000.mp4");
        //        OSSUtils.getVideoList("abkj-test","/course",1000,"a82898608dee482181a8a973359ae1c0");
        //        List<String> videoList = OSSUtils.getVideoList(buketName, "/course", 1000, "a82898608dee482181a8a973359ae1c0");
        //        System.out.println(videoList.toString());
        //        videoList.forEach(s -> {
        //            OSSUtils.downloadFile("abkj-test","a82898608dee482181a8a973359ae1c0/course/1/10101000.mp4","C:\\Users\\Administrator\\Desktop\\work\\video\\"+s);
        //创建本地文件夹
        //            FileUtil.isExistDir("C:/www/course/1/");
        //            OSSUtils.downloadFile(buketName,"a82898608dee482181a8a973359ae1c0/course/1/10101000.mp4","C:/www/course/1/10101000.mp4");
        //        });

        //        String s = "course/1/10101000.mp4";
        //        String[] split = s.split("course/");
        //        System.out.println(split[1]);
        //断点续传
//        breakpointContinuingly("abzykj-test", "a82898608dee482181a8a973359ae1c0/course/1/20899203.mp4", "C:\\www\\course\\0\\13974000.mp4", "D:/video/a.mp4", "video/plain");
        //断点续传下载
//        breakpointDownload("abzykj-test", "20899203.mp4", "C:\\video\\course\\1\\" + "20899203.mp4", "D:/video/" + "20899203.mp4");

//        List<String> url = getVideoListByPage("abzykj-test", "/course", "a82898608dee482181a8a973359ae1c0", 1, "1");
//        System.out.println(url.toString());
//
//        String objectUrl = getObjectUrl("course/1/aa430dc73f6e6f8883827ef05a941991.mp4");
//        System.out.println(objectUrl);
        delFile("老鼠的爱情.mp4","abzy-video");
    }


}
